<?php

namespace common\services\tool;

use Yii;
use DateTime;
use DateTimeZone;
use common\services\tool\ToolString;

/**
 * 时间处理相关工具
 *
 * Class ToolTime
 * @package common\services\tool
 */
class ToolTime
{

    /**
     * 将时间转化成时间戳
     * @param null $time
     * @return false|int|null
     */
    public static function getTimeStamp($time = null)
    {
        if ($time === null || $time == 'time()') {
            $time = time();
        }
        $date = null;
        if (ToolString::isInt($time)) {
            if (strlen($time) == 13) {
                $time = substr($time, 0, 10);
            }
            $date = intval($time);
        } else if (is_string($time)) {
            $date = strtotime($time);
        } else if (is_subclass_of($time, 'DateTime')) {
            $date = $time->getTimestamp();
        }
        return $date;
    }

    /**
     * 将毫秒时间转化成字符串
     * @param null $microTime 毫秒时间戳
     * @param string $format
     * @return string
     */
    public static function microTimeToStr($microTime = null, $format = 'Y-m-d H:i:s.u e')
    {
        if (is_null($microTime)) {
            $microTime = microtime(true);
        }
        return DateTime::createFromFormat('U.u', sprintf("%.6f", $microTime))
            ->setTimeZone(new DateTimeZone(date_default_timezone_get()))
            ->format($format);
    }

    /**
     * 取得两个时间（字符串或时间戳）之间的时间差距（秒）
     * @param null $time1 待比较时间
     * @param null $time2 被比较时间（默认是当前时间）
     * @return false|int|null       时间差（秒） ，负数 说明前者在后者之前。
     */
    public static function getTimeDifference($time1 = null, $time2 = null)
    {
        return self::getTimeStamp($time1) - self::getTimeStamp($time2);
    }

    /**
     * 取得两个时间（字符串或时间戳）之间的时间差距（秒）
     * @param null $time1 待比较时间
     * @param null $time2 被比较时间（默认是当前时间）
     * @return int           时间差（秒） ，负数 说明前者在后者之前。
     */
    public static function getTimeBetweenDays($time1 = null, $time2 = null)
    {
        $time1 = date("Y-m-d", $time1);
        $time2 = date("Y-m-d", $time2);
        $s = self::getTimestamp($time1) - self::getTimestamp($time2);
        $day = intval($s / 3600 / 24);
        return $day;
    }

    /**
     * 获取指定时间距离当前时间过了多少天
     * @param null $time
     * @return int
     */
    public static function getDayPassed($time = null)
    {
        $time1 = date("Y-m-d H:i:s", $time);
        $time2 = date("Y-m-d H:i:s");
        $s = static::getTimeDifference($time2, $time1);
        $day = intval($s / 3600 / 24);
        return $day;
    }

    /**
     * 日期增减
     * @param null $datetime
     * @param int $add 相应地,要增加月,年,将day改成month或year即可
     * @return false|null|string
     */
    public static function getDateAdd($datetime = null, $add = 1)
    {
        if (!$datetime) {
            $datetime = date("Y-m-d");
        }
        if (isset($add)) {
            date_default_timezone_set('PRC'); //默认时区
            if ($add > 0) {
                $add = " + " . $add;
            }
            //当前的时间增加5天
            return date('Y-m-d', strtotime("{$datetime} {$add} day"));  //输出结果：2014-11-16
        }
        return $datetime;
    }

    /**
     * 将时间转化成字符串
     * @param null $time
     * @param string $format
     * @return false|string
     */
    public static function timeToStr($time = null, $format = 'Y-m-d H:i:s')
    {
        return date($format, self::getTimestamp($time));
    }

    /**
     * 时间转化成当前时间的对应关系
     * @param null $p_time
     * @return string
     */
    public static function getTimeToStringBetweenDateTimeWithToday($p_time = null)
    {
        $p_time = self::getTimeStamp($p_time);
        $_interval = self::getTimeDifference($p_time, time());
        $_isBeforeOrAfter = $_interval > 0 ? false : true;
        $_r = '未知';
        if ($_interval < -60 * 60 * 24 * 30 * 12) {
            $_r = sprintf('%s年前 %s', 0 - intval($_interval / 60 / 60 / 24 / 30 / 12), self::timeToStr($p_time, 'Y-m-d H:i'));
        } else if ($_interval < -60 * 60 * 24 * 30) {
            $_r = sprintf('%s月前 %s', 0 - intval($_interval / 60 / 60 / 24 / 30), self::timeToStr($p_time, 'Y-m-d H:i'));
        } else if ($_interval < -60 * 60 * 24 * 7) {
            $_r = sprintf('%s周前 %s', 0 - intval($_interval / 60 / 60 / 24 / 7), self::timeToStr($p_time, 'Y-m-d H:i'));
        } else if ($_interval < -60 * 60 * 24 * 2) {
            $_r = sprintf('%s天前 %s', 0 - intval($_interval / 60 / 60 / 24), self::timeToStr($p_time, 'Y-m-d H:i'));
        } else if ($_interval < -60 * 60 * 24 * 2) {
            $_r = sprintf('%s天前 %s', 0 - intval($_interval / 60 / 60 / 24), self::timeToStr($p_time, 'Y-m-d H:i'));
        } else if (self::getTimeDifference($p_time, date("Y-m-d 00:00:00", strtotime("-1 day"))) < 0) {
            $_r = sprintf('前天 %s', self::timeToStr($p_time, 'H:i:s'));
        } else if (self::getTimeDifference($p_time, date("Y-m-d 00:00:00", time())) < 0) {
            $_r = sprintf('昨天 %s', self::timeToStr($p_time, 'H:i:s'));
        } else if ($_interval < -60 * 60 * 2) {
            $_r = sprintf('今天 %s', self::timeToStr($p_time, 'H:i:s'));
        } else if ($_interval < -60 * 60) {
            $_r = sprintf('一小时前 %s', self::timeToStr($p_time, 'H:i:s'));
        } else if ($_interval < -60) {
            $_r = sprintf('%s分钟%s %s', 0 - intval($_interval / 60), $_isBeforeOrAfter ? '前' : '内', self::timeToStr($p_time, 'H:i:s'));
        } else if ($_interval < 0) {
            $_r = sprintf('刚才 %s', self::timeToStr($p_time, 'H:i:s'));
        } else if ($_interval < 60) {
            $_r = sprintf('马上 %s', self::timeToStr($p_time, 'H:i:s'));
        } else if ($_interval < 60 * 60) {
            $_r = sprintf('%s分钟内 %s', intval($_interval / 60), self::timeToStr($p_time, 'H:i:s'));
        } else if ($_interval < 60 * 60 * 2) {
            $_r = sprintf('一小时后 %s', self::timeToStr($p_time, 'H:i:s'));
        } else if (self::getTimeDifference($p_time, date("Y-m-d 00:00:00", strtotime("+1 day"))) < 0) {
            $_r = sprintf('今天 %s', self::timeToStr($p_time, 'H:i:s'));
        } else if (self::getTimeDifference($p_time, date("Y-m-d 00:00:00", strtotime("+2 day"))) < 0) {
            $_r = sprintf('明天 %s', self::timeToStr($p_time, 'H:i:s'));
        } else if ($_interval < 60 * 60 * 24 * 7) {
            $_r = sprintf('%s天后 %s', intval($_interval / 60 / 60 / 24), self::timeToStr($p_time, 'Y-m-d H:i'));
        } else if ($_interval < 60 * 60 * 24 * 30) {
            $_r = sprintf('%s周后 %s', intval($_interval / 60 / 60 / 24 / 7), self::timeToStr($p_time, 'Y-m-d H:i'));
        } else if ($_interval < 60 * 60 * 24 * 30 * 12) {
            $_r = sprintf('%s月后 %s', intval($_interval / 60 / 60 / 24 / 30), self::timeToStr($p_time, 'Y-m-d H:i'));
        } else {
            $_r = sprintf('%s年后 %s', intval($_interval / 60 / 60 / 24 / 30 / 12), self::timeToStr($p_time, 'Y-m-d H:i'));
        }
        return $_r;
    }

    /**
     * 将N秒转化成其他单位的字符串
     * @param null $_interval
     * @param string $p_format
     * @return mixed|string
     */
    public static function secondsToStr($_interval = null, $p_format = 'Y年m月d天H小时i分钟s秒')
    {
        $_r = $p_format;

        if (strpos($_r, 'Y') !== false) {
            $_y = intval($_interval / 60 / 60 / 24 / 30 / 12);
            $_interval -= $_y * 60 * 60 * 24 * 30 * 12;
            $_r = str_replace('Y', sprintf('%02d', $_y), $_r);
        }

        if (strpos($_r, 'm') !== false) {
            $_y = intval($_interval / 60 / 60 / 24 / 30);
            $_interval -= $_y * 60 * 60 * 24 * 30;
            $_r = str_replace('m', sprintf('%02d', $_y), $_r);
        }

        if (strpos($_r, 'd') !== false) {
            $_y = intval($_interval / 60 / 60 / 24);
            $_interval -= $_y * 60 * 60 * 24;
            $_r = str_replace('d', sprintf('%02d', $_y), $_r);
        }

        if (strpos($_r, 'H') !== false) {
            $_y = intval($_interval / 60 / 60);
            $_interval -= $_y * 60 * 60;
            $_r = str_replace('H', sprintf('%02d', $_y), $_r);
        }

        if (strpos($_r, 'i') !== false) {
            $_y = intval($_interval / 60);
            $_interval -= $_y * 60;
            $_r = str_replace('i', sprintf('%02d', $_y), $_r);
        }

        if (strpos($_r, 's') !== false) {
            $_y = intval($_interval);
            $_interval -= $_y;
            $_r = str_replace('s', sprintf('%02d', $_y), $_r);
        }

        return $_r;
    }
}